// Package apperror 自定义错误处理
package apperror

import (
	"errors"
	"strconv"
	"strings"
)

// AppError 应用错误
type AppError struct {
	Code    int64
	Message string
}

// NewAppError 获取应用错误处理器
func NewAppError(code int64, message string) *AppError {
	return &AppError{
		Code:    code,
		Message: message,
	}
}

// NewTypeError 获取类型化错误处理器
func NewTypeError(errType ErrorType) *AppError {
	errArr := strings.Split(string(errType), "||")
	if len(errArr) != 2 {
		return &AppError{
			Code:    500,
			Message: string(errType),
		}
	}

	code, err := strconv.ParseInt(errArr[0], 10, 64)
	if err != nil {
		return &AppError{
			Code:    500,
			Message: errArr[1],
		}
	}

	return &AppError{
		Code:    code,
		Message: errArr[1],
	}
}

// 获取错误消息
func (e *AppError) Error() string {
	return e.Message
}

// ErrorCode 获取错误编码
func (e *AppError) ErrorCode() int64 {
	return e.Code
}

// AsAppError 错误转换为应用错误
func AsAppError(err error) (*AppError, bool) {
	var appErr *AppError
	ok := errors.As(err, &appErr)
	return appErr, ok
}

// IsAppError 是否是应用错误
func IsAppError(err error) bool {
	var appError *AppError
	ok := errors.As(err, &appError)
	return ok
}

// GetAppErrorCode 获取应用错误编码
func GetAppErrorCode(err error) int64 {
	if err == nil {
		return 0
	}

	var appErr *AppError
	if errors.As(err, &appErr) {
		return appErr.Code
	}
	return 500
}
